package cn.hznc.configuration;

import cn.hznc.domain.entity.MinioProp;
import cn.hznc.utils.FileUtils;
import cn.hznc.utils.MockMultipartFile;
import com.alibaba.excel.util.StringUtils;
import io.minio.*;
import io.minio.http.Method;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;

/**
 * @Author：Administrator
 * @Date：2023/4/19 10:45
 */
@Component
@EnableConfigurationProperties(MinioProp.class)
@Slf4j
public class MinioHelper{

//    public static void main(String[] args) {
//        test();
//        test1();
//    }
//
//    private static void test(){
//        char startLetter = 'A'; // 起始字母
//        char endLetter = (char) (startLetter + 1);
//        System.out.println(endLetter);
//    }
//
//    private static void test1(){
//        System.out.println(Integer.parseInt("021"));
//    }


    @Autowired
    private MinioProp minioProp;

    @Autowired
    private MinioClient minioClient;

    /**
     * 上传文件
     * @param file
     * @param filename
     */
    public void uploadFile(MultipartFile file , String filename){
        try {
            // 使用putObject上传一个文件到存储桶中。
            InputStream inputStream = file.getInputStream();
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(minioProp.getBucketName())
                    .object(filename)
                    .contentType(file.getContentType())
                    .stream(inputStream , file.getSize() , -1)
                    .build());
        } catch (Exception e) {
            log.error("uploadFile exception {}" + e.getMessage());
        }
    }

    /**
     * 上传微信头像
     *
     * @param url 网络图片地址
     * @return
     */
    public void uploadFileWithNetFile(String url) throws IOException {
        URL url1 = new URL(url);
        InputStream onlineInputStream = url1.openStream();
        if (StringUtils.isBlank(url)) {
            return;
        }
        try {
            MultipartFile copyFile = new MockMultipartFile(ContentType.MULTIPART_FORM_DATA.toString(), onlineInputStream);

            InputStream uploadInputStream = copyFile.getInputStream();
            // 判断上传文件是否为空
            if (null == uploadInputStream) {
                return;
            }
            String[] split = url.split("\\/");
            String filename = split[split.length-1];
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(minioProp.getBucketName())
                    .object(filename)
                    .contentType(ContentType.MULTIPART_FORM_DATA.toString())
                    .stream(uploadInputStream , copyFile.getSize() , -1)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

//    public void uploadFileWithNetFileReload(InputStream inputStream , String url) {
////        if (StringUtils.isBlank(url)) {
////            return;
////        }
//        try {
//            //InputStream inputStream = FileUtils.returnBitMap(url);
//            //MultipartFile file = new MockMultipartFile(ContentType.MULTIPART_FORM_DATA.toString(), inputStream);
//            URL imageUrlObj = new URL("http://dtl.zccct.com:8188/images/6406R/OutputJT/638491373222253328.pdf");
//            ReadableByteChannel rbc = Channels.newChannel(imageUrlObj.openStream());
////            URL imageUrlObj = new URL(imageUrl);
////            ReadableByteChannel rbc = Channels.newChannel(imageUrlObj.openStream());
//            //rbc.read()
//
//            //MultipartFile file = (MultipartFile) new File(url);
//            // 判断上传文件是否为空
//            if (null == inputStream) {
//                return;
//            }
//            String[] split = url.split("\\/");
//            String filename = split[split.length-1];
//            minioClient.putObject(PutObjectArgs.builder()
//                    .bucket(minioProp.getBucketName())
//                    .object(filename)
//                    .contentType(ContentType.MULTIPART_FORM_DATA.toString())
//                    .stream(rbc , 1 , -1)
//                    .build());
//            //return minioProp.getEndpoint() + "/" + MinioConst.MINIO_BUCKET + "/" + fileName;
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }

    /**
     * 获取文件
     * @param response
     * @param filename
     */
    @SneakyThrows
    public void downloadGetObject(HttpServletResponse response ,String filename) {
        String bucketName = minioProp.getBucketName();
        //构建输入流获取minio中的数据
        GetObjectResponse minioInputStream
                = minioClient.getObject(GetObjectArgs.builder()
                .bucket(bucketName)
                .object(filename)
                .build());
        response.reset();
        response.setHeader("Content-Disposition", "attachment;filename= " + filename);
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("utf-8");
        ServletOutputStream outputStream = response.getOutputStream();
        byte[] buff = new byte[1024];
        int len = 0;
        while ((len = minioInputStream.read(buff)) != -1) {
            outputStream.write(buff, 0, len);
        }
        outputStream.flush();
    }

    /**
     * 获取文件
     * @param response
     * @param filename
     */
    @SneakyThrows
    public void downloadGetObjectStream(HttpServletResponse response ,String filename) {
        String bucketName = minioProp.getBucketName();
        //构建输入流获取minio中的数据
        GetObjectResponse minioInputStream
                = minioClient.getObject(GetObjectArgs.builder()
                .bucket(bucketName)
                .object(filename)
                .build());
        response.reset();
        response.setHeader("Content-Disposition", "attachment;filename= " + filename);
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("utf-8");
        ServletOutputStream outputStream = response.getOutputStream();
        byte[] buff = new byte[1024];
        int len = 0;
        while ((len = minioInputStream.read(buff)) != -1) {
            outputStream.write(buff, 0, len);
        }
        outputStream.flush();
    }

    /**
     * 获取文件访问地址
     * @param response
     * @param filename
     * @return
     */
    @SneakyThrows
    public String downloadGetObjectUrl(HttpServletResponse response ,String filename) {
        String bucketName = minioProp.getBucketName();
        //构建输入流获取minio中的数据
        return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                .method(Method.GET)
                .bucket(bucketName)
                .object(filename)
                .build());
    }

    /**
     * 获取文件访问地址
     * @param filename
     * @return
     */
    @SneakyThrows
    public String downloadGetObjectUrlReload(String filename) {
        String bucketName = minioProp.getBucketName();
        //构建输入流获取minio中的数据
        return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                .method(Method.GET)
                .bucket(bucketName)
                .object(filename)
                .build());
    }


    /**
     * 从指定桶中删除文件
     * @param filename
     */
    @SneakyThrows
    public void removeFile(String filename){
        minioClient.removeObject(RemoveObjectArgs
                .builder()
                .bucket(minioProp.getBucketName())
                .object(filename)
                .build());
    }


}
